
#define ESP_NO_CLIENT 0
#define ESP_SERIAL_CLIENT 1
#define ESP_TELNET_CLIENT 2
#define ESP_HTTP_CLIENT 4
#define ESP_WEBSOCKET_TERMINAL_CLIENT 8
#define ESP_REMOTE_SCREEN_CLIENT 16
#define ESP_STREAM_HOST_CLIENT 30
#define ESP_BT_CLIENT 32
#define ESP_SCREEN_CLIENT 64
#define ESP_WEBSOCKET_CLIENT 128
#define ESP_SOCKET_SERIAL_CLIENT 129
#define ESP_ECHO_SERIAL_CLIENT 130
#define ESP_SERIAL_BRIDGE_CLIENT 150
#define ESP_ALL_CLIENTS 255

#define ESP_STREAM_HOST_OUTPUT ESP_SERIAL_CLIENT

#define ESP_OUTPUT_IP_ADDRESS 0
#define ESP_OUTPUT_STATUS 1
#define ESP_OUTPUT_PROGRESS 2
#define ESP_OUTPUT_STATE 3

#define ESP_STATE_DISCONNECTED 0

#ifndef _ESPOUTPUT_H
#define _ESPOUTPUT_H

#include "Print.h"
#include "espconfig.h"
#if defined(ARDUINO_ARCH_ESP32)
class WebServer;
#define WEBSERVER WebServer
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#define WEBSERVER ESP8266WebServer
#endif // ARDUINO_ARCH_ESP8266

class ESPOutput : public Print
{
public:
    ESPOutput(WEBSERVER *webserver);
    ~ESPOutput();
    size_t write(const uint8_t *buffer, size_t size);

    inline size_t write(const char *s)
    {
        return write((uint8_t *)s, strlen(s));
    }
    inline size_t write(unsigned long n)
    {
        return write((uint8_t)n);
    }
    inline size_t write(long n)
    {
        return write((uint8_t)n);
    }
    inline size_t write(unsigned int n)
    {
        return write((uint8_t)n);
    }
    inline size_t write(int n)
    {
        return write((uint8_t)n);
    }
    size_t dispatch(const uint8_t *sbuf, size_t len);
    size_t printMSG(const char *s, bool withNL = true);
    size_t printMSGLine(const char *s);
    size_t printERROR(const char *s, int code_error = 500);
    size_t printLN(const char *s);
    void flush();
    static const char *encodeString(const char *s);
    bool footerSent()
    {
        return _footerSent;
    }

private:
    int _code;
    bool _headerSent;
    bool _footerSent;
    WEBSERVER *_webserver;
};

#endif //_ESPOUTPUT_H
